package cn.xiaolang.function.design_pattern.dynamic.proxy.pattern.jdk;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * jdk的动态代理方式：java.lang.reflect中的Proxy和InvocationHandler方法
 * 局限性：只能对实现了接口的类生成代理，而不能针对类，如果要代理的类，没有接口就只能使用cglib动态代理了
 *
 * @author DeanKano
 * @date 2016年4月19日
 */
@Slf4j
public class JdkProxyFactory implements InvocationHandler {

    //实现接口的目标类
    private final Object delegate;

    public JdkProxyFactory(Object delegate) {
        this.delegate = delegate;
    }

    /**
     * 获取目标类代理示例
     *
     * @return 目标类代理类
     */
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
    }

    /**
     * 通过反射执行，原始对象的方法
     * 正常情况下：都是对象.方法的调用形式
     * 反射：通过method方法反射.对象
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.info("前置增强：{}", method.getName());
        Object invoke = method.invoke(this.delegate, args);
        log.info("后置增强：{}", method.getName());
        return invoke;
    }

}
